﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using System.Data;
using System.Xml;
using System.Data.SqlTypes;
using DTO = Microsoft.MSE.Catalog.Contracts;

namespace Microsoft.MSE.Catalog.Module.Data
{
    public class MessageHeader
    {
        public static void CreateMessageHeader(DTO.MessageHeader header, Guid operationVersionID, int ordinal, bool isRequestHader, SqlTransaction txn, SqlConnection conn)
        {
            Guid ID;
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[CreateMessageHeaderForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@ID", SqlDbType.UniqueIdentifier);
                    SqlParameter OperationVersionIDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter NameParam = new SqlParameter("@Name", SqlDbType.NVarChar, 400);
                    SqlParameter IsRequiredParam = new SqlParameter("@IsRequired", SqlDbType.Bit);
                    SqlParameter IsRequestHeaderParam = new SqlParameter("@IsRequestHeader", SqlDbType.Bit);
                    SqlParameter OrdinalParam = new SqlParameter("@Ordinal", SqlDbType.Int);
                    SqlParameter ProtectionLevelParam = new SqlParameter("@ProtectionLevel", SqlDbType.NVarChar, 32);
                    SqlParameter SchemaObjectIDParam = new SqlParameter("@SchemaObjectID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;

                    IDParam.Direction = ParameterDirection.Output;
                    OperationVersionIDParam.Value = operationVersionID;
                    NameParam.Value = header.Name;
                    SchemaObjectIDParam.Value = header.SchemaObject.ID;
                    if (((Guid)SchemaObjectIDParam.Value) == Guid.Empty)
                    {
                        throw new ApplicationException("Attempt to create message header with invalid SchemaObject");
                    }
                    IsRequiredParam.Value = header.IsRequired;
                    IsRequestHeaderParam.Value = isRequestHader;
                    OrdinalParam.Value = ordinal;
                    ProtectionLevelParam.Value = header.ProtectionLevel.ToString();

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(OperationVersionIDParam);
                    cmd.Parameters.Add(NameParam);
                    cmd.Parameters.Add(SchemaObjectIDParam);
                    cmd.Parameters.Add(IsRequiredParam);
                    cmd.Parameters.Add(IsRequestHeaderParam);
                    cmd.Parameters.Add(OrdinalParam);
                    cmd.Parameters.Add(ProtectionLevelParam);

                    cmd.ExecuteNonQuery();
                    ID = (Guid)IDParam.Value;
                    header.ID = ID;
                }

            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }
        }

        public static void DeleteMessageHeaders(Guid ID, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            const string sprocname = "[ServiceEngine].[DeleteMessageHeadersForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    cmd.Parameters.Add(IDParam);

                    cmd.ExecuteNonQuery();
                }

            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }
        }

        public static List<DTO.MessageHeader> GetMessageHeaders(Guid ID,bool isRequestHeader, SqlTransaction txn, SqlConnection conn)
        {
            bool autoclose = false;
            List<DTO.MessageHeader> messageHeaders = new List<DTO.MessageHeader>();
            const string sprocname = "[ServiceEngine].[GetMessageHeadersForOperationVersion]";

            try
            {
                if (conn == null) conn = CatalogSvcHelper.GetConnection();
                if (conn.State == ConnectionState.Closed)
                {
                    autoclose = true;
                    conn.Open();
                }

                using (SqlCommand cmd = new SqlCommand(sprocname, conn, txn))
                {
                    SqlParameter IDParam = new SqlParameter("@OperationVersionID", SqlDbType.UniqueIdentifier);
                    SqlParameter IsRequestHeaderParam = new SqlParameter("@IsRequestHeader", SqlDbType.Bit);

                    cmd.CommandType = CommandType.StoredProcedure;
                    IDParam.Value = ID;
                    IsRequestHeaderParam.Value = isRequestHeader;

                    cmd.Parameters.Add(IDParam);
                    cmd.Parameters.Add(IsRequestHeaderParam);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            while (reader.Read())
                            {
                                DTO.MessageHeader header = new DTO.MessageHeader();
                                header.ID = reader.GetGuid(0);
                                header.Name = reader.GetString(1);
                                header.IsRequired = reader.GetBoolean(2);
                                header.ProtectionLevel = (System.Net.Security.ProtectionLevel)Enum.Parse(typeof(System.Net.Security.ProtectionLevel), reader.GetString(3));
                                header.SchemaObject = SchemaObject.GetSchemaObject(reader.GetGuid(4), txn, conn);
                                messageHeaders.Add(header);
                            }
                        }
                    }
                }
            }
            finally
            {
                if (autoclose && (conn != null)) conn.Close(); //Close connection if opened in this method
            }

            return messageHeaders;

        }
    }
}
